﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Common.Encrypt
{
    /// <summary>
    /// AES加密（非标准AES，秘钥是通过MD5摘要获取，如需指定秘钥不要使用此对象，使用<see cref="AesCryptoProvider"/>代替）
    /// </summary>
    public static class AESProvider
    {
        /// <summary>
        /// 默认秘钥
        /// </summary>
        public const string _keys = "3C02A379965AB0DFCD77B1C484450433";

        #region Decode 解密

        /// <summary>
        /// 将密文字符串解码成明文
        /// </summary>
        /// <param name="decryptString">密文字符串</param>
        /// <returns>返回解码后的明文</returns>
        public static string Decode(string decryptString)
        {
            return Decode(decryptString, _keys);
        }

        /// <summary>
        /// 将密文字符串解码成明文
        /// </summary>
        /// <param name="decryptString">密文字符串</param>
        /// <param name="keys">解密的密钥</param>
        /// <returns>返回解码后的明文</returns>
        public static string Decode(string decryptString, string keys)
        {
            byte[] buffer = Convert.FromBase64String(decryptString);
            byte[] result = Decode(buffer, keys);
            return Encoding.UTF8.GetString(result);
        }

        /// <summary>
        /// 将密文字节数组解码成明文字节数组
        /// </summary>
        /// <param name="buffer">密文字节数组</param>
        /// <returns>返回明文字节数组</returns>
        public static byte[] Decode(byte[] buffer)
        {
            return Decode(buffer, _keys);
        }

        /// <summary>
        /// 将密文字节数组解码成明文字节数组
        /// </summary>
        /// <param name="buffer">密文字节数组</param>
        /// <param name="keys">解密密钥</param>
        /// <returns>返回明文字节数组</returns>
        public static byte[] Decode(byte[] buffer, string keys)
        {
            byte[] rgbKey = Encoding.UTF8.GetBytes(MD5Provider.Encode(keys, Encoding.UTF8).Substring(0, 8));
            byte[] rgbIV = rgbKey;
            DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
            MemoryStream stream = new MemoryStream();
            CryptoStream stream2 = new CryptoStream(stream, provider.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
            stream2.Write(buffer, 0, buffer.Length);
            stream2.FlushFinalBlock();
            return stream.ToArray();
        }
        #endregion

        #region Encode 加密

        /// <summary>
        /// 将明文字符串编码成密文字符串
        /// </summary>
        /// <param name="encryptString">明文字符串</param>
        /// <returns>返回一段密文字符串</returns>
        public static string Encode(string encryptString)
        {
            return Encode(encryptString, _keys);
        }

        /// <summary>
        /// 将明文字符串编码成密文字符串
        /// </summary>
        /// <param name="encryptString">明文字符串</param>
        /// <param name="keys">编码密钥</param>
        /// <returns>返回一段密文字符串</returns>
        public static string Encode(string encryptString, string keys)
        {
            Debug.WriteLine("DES加密：");
            Debug.WriteLine("DES数据：" + encryptString);
            Debug.WriteLine("DES秘钥：" + keys);
            byte[] buffer = Encoding.UTF8.GetBytes(encryptString);
            byte[] result = Encode(buffer, keys);
            return Convert.ToBase64String(result);
        }

        /// <summary>
        /// 将明文字节数组编码成密文字节数组
        /// </summary>
        /// <param name="buffer">明文字节数组</param>
        /// <param name="keys">编码密钥</param>
        /// <returns>返回一段密文字节数组</returns>
        public static byte[] Encode(byte[] buffer, string keys)
        {
            string md5_keys = MD5Provider.Encode(keys, Encoding.UTF8);
            string subString = md5_keys.Substring(0, 8);

            Debug.WriteLine("对DES秘钥再次MD5确保秘钥：" + md5_keys);
            Debug.WriteLine("取2次MD5前8位作为最终秘钥：" + subString);

            byte[] rgbKey = Encoding.UTF8.GetBytes(subString);
            byte[] rgbIV = rgbKey;
            DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
            MemoryStream stream = new MemoryStream();
            CryptoStream stream2 = new CryptoStream(stream, provider.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
            stream2.Write(buffer, 0, buffer.Length);
            stream2.FlushFinalBlock();
            return stream.ToArray();
        }

        /// <summary>
        /// 将明文字节数组编码成密文字节数组
        /// </summary>
        /// <param name="buffer">明文字节数组</param>
        /// <returns>返回一段密文字节数组</returns>
        public static byte[] Encode(byte[] buffer)
        {
            return Encode(buffer, _keys);
        }
        #endregion
    }
}
